import asyncio
from typing import Dict, Any

import httpx
import logging

logger = logging.getLogger(__name__)


async def send_get_request(
        url: str,
        params: Dict[str, Any] | None = None,
        timeout: httpx.Timeout | None = None,
        headers: Dict[str, Any] | None = None,
        max_retries: int = 3,
        retry_delay: float = 2.0
) -> Dict[str, Any] | None:
    """
    发送GET请求并返回响应结果，支持错误处理和日志记录
    :param url: 请求的URL
    :param params: 请求的查询参数（可选）
    :param timeout: 自定义的超时时间（可选）
    :param headers: 请求头（可选）
    :param max_retries: 最大重试次数（默认3次）
    :param retry_delay: 重试延迟时间（秒，默认2秒）
    :return: 响应结果 JSON 或 None
    """
    if timeout is None:
        timeout = httpx.Timeout(connect=10.0, read=30.0, write=10.0, pool=10.0)

    for attempt in range(1, max_retries + 1):
        try:
            logger.info(f"开始发送GET请求: {url}，参数: {params}, 尝试次数: {attempt}")
            async with httpx.AsyncClient(timeout=timeout) as client:
                response = await client.get(url, params=params, headers=headers)
                response.raise_for_status()  # 如果响应状态码为 4xx 或 5xx，会抛出异常
            logger.info(f"GET请求成功: {url}，状态码: {response.status_code}")
            return response.json()

        except httpx.HTTPStatusError as e:
            logger.error(f"GET请求失败: {url}, 状态码 {e.response.status_code}, 原因: {e.response.content.decode()}")
        except httpx.TimeoutException as e:
            logger.warning(f"POST请求超时: {url}, 尝试第{attempt}次, 原因: {e}")
            if attempt < max_retries:
                await asyncio.sleep(retry_delay)
        except Exception as e:
            logger.error(f"请求发生未知错误: {url}, 原因: {e}")


async def send_post_request(
        url: str,
        json_data: Dict[str, Any] | None = None,
        timeout: httpx.Timeout | None = None,
        headers: Dict[str, Any] | None = None,
        max_retries: int = 3,
        retry_delay: float = 2.0
) -> Dict[str, Any] | None:
    """
    发送POST请求并返回响应结果，支持错误处理和日志记录
    :param url: 请求的URL
    :param json_data: 请求体中的JSON数据（可选）
    :param timeout: 自定义的超时时间（可选）
    :param headers: 请求头（可选）
    :param max_retries: 最大重试次数（默认3次）
    :param retry_delay: 重试延迟时间（秒，默认2秒）
    :return: 响应结果 JSON 或 None
    """
    if timeout is None:
        timeout = httpx.Timeout(connect=10.0, read=30.0, write=10.0, pool=10.0)

    for attempt in range(1, max_retries + 1):
        try:
            logger.info(f"开始发送POST请求: {url}，数据: {json_data}")
            async with httpx.AsyncClient(timeout=timeout) as client:
                response = await client.post(url, json=json_data, headers=headers)
                response.raise_for_status()  # 如果响应状态码为 4xx 或 5xx，会抛出异常
            logger.info(f"POST请求成功: {url}，状态码: {response.status_code}")
            return response.json()

        except httpx.HTTPStatusError as e:
            logger.error(f"POST请求失败: {url}, 状态码 {e.response.status_code}, 原因: {e.response.content.decode()}")
        except httpx.TimeoutException as e:
            logger.warning(f"POST请求超时: {url}, 尝试第{attempt}次, 原因: {e}")
            if attempt < max_retries:
                await asyncio.sleep(retry_delay)
        except Exception as e:
            logger.error(f"请求发生未知错误: {url}, 原因: {e}")
